package com.xmy.cultivate.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmy.cultivate.entity.OrderDisClan;
import com.xmy.cultivate.entity.RatePay;
import com.xmy.cultivate.entity.RateQuantityPay;
import com.xmy.cultivate.entity.RateQuantityPayOrder;
import com.xmy.cultivate.mapper.RateQuantityPayMapper;
import com.xmy.cultivate.mapper.RateQuantityPayOrderMapper;
import com.xmy.cultivate.service.IOrderDetailService;
import com.xmy.cultivate.service.IOrderDisClanService;
import com.xmy.cultivate.service.IRatePayService;
import com.xmy.cultivate.service.IRateQuantityPayService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;

/**
 * <p>
 * 多期缴费量 服务实现类
 * </p>
 *
 * @author hpiggy
 * @since 2025-06-18
 */
@Service
public class RateQuantityPayServiceImpl extends ServiceImpl<RateQuantityPayMapper, RateQuantityPay> implements IRateQuantityPayService {

    @Autowired
    RateQuantityPayMapper rateQuantityPayMapper;

    @Autowired
    RateQuantityPayOrderMapper rateQuantityPayOrderMapper;

    @Autowired
    IOrderDisClanService iOrderDisClanService;

    @Autowired
    IOrderDetailService iOrderDetailService;

    @Autowired
    IRatePayService iRatePayService;


    /**
     * 多期缴费量数据统计：单科两期、双科同时报名或兄弟姐妹分别报名均可视为两期连报
     *
     * 一、单科两期、多科同时报名均可视为两期连报
     *     1、同一天内学生A报了英语2期
     *         个人数据
     *             算英语老师多期缴费成功1次
     *
     *         管理数据（校区数据）
     *             算英语老师所属校区多期缴费成功1次
     *
     *     2、同一天内学生A报了英语1期、报了数学1期，多期缴费成功
     *         个人数据
     *             算英语老师多期缴费成功1次
     *             算数学老师多期缴费成功1次
     *
     *         管理数据（校区数据）
     *             在同一个校区
     *                 算学生所在校区多期缴费成功1次
     *
     *             在不同校区
     *                 算学生英语科目所在校区多期缴费成功1次
     *                 算学生数据科目所在校区多期缴费成功1次
     *
     * 二、将家庭整体缴费情况纳入统计，例如一个家庭中两个孩子分别报名不同科目，也算作两期连报
     *     1、同一天内学生A报了英语1期，亲戚（兄弟姐妹）学生B报了英语1期
     *         个人数据
     *             算学生A英语老师多期缴费成功1次
     *             算学生B英语老师多期缴费成功1次
     *
     *         管理数据（校区数据）
     *             在同一个校区
     *                 算学生所在校区多期缴费成功1次
     *
     *             在不同校区
     *                 算学生A所在校区多期缴费成功1次
     *                 算学生B所在校区多期缴费成功1次
     *
     *     2、同一天内学生A报了英语1期，亲戚（兄弟姐妹）学生B报了数学1期，算学生A多期缴费成功，算学生B多期缴费成功
     *         个人数据
     *             算学生A英语老师多期缴费成功1次
     *             算学生B数学老师多期缴费成功1次
     *
     *         管理数据（校区数据）
     *             在同一个校区
     *                 算学生所在校区多期缴费成功1次
     *
     *             在不同校区
     *                 算学生A所在校区多期缴费成功1次
     *                 算学生B所在校区多期缴费成功1次
     */
    @Override
    public void rateQuantityPay(RateQuantityPay rateQuantityPay) {
        // 获取当前日期
        LocalDate today = LocalDate.now();
        Integer yearPart = rateQuantityPay.getYearPart();
        Integer quarterNum = rateQuantityPay.getQuarterNum();
        Long studentId = rateQuantityPay.getStudentId();
        Integer lessonType = rateQuantityPay.getLessonType();
        String addDate = String.valueOf(today);

        // 查询当天的报名数据
        List<RatePay> ratePayList = iRatePayService.getRatePayByStudentId(yearPart, quarterNum, lessonType, addDate, studentId, null, 1);

        // 处理单科两期
        processRatePays(ratePayList, null, yearPart, quarterNum, studentId, null, lessonType, addDate, 1);

        // 处理多科同时报名
        processRatePays(ratePayList, null, yearPart, quarterNum, studentId, null, lessonType, addDate, 2);

        // 处理亲属报名
        List<OrderDisClan> orderDisClanList = iOrderDisClanService.getOrderDisClanByStudentId(rateQuantityPay.getStudentId());
        for (OrderDisClan orderDisClan : orderDisClanList) {
            List<RatePay> ratePayToList = iRatePayService.getRatePayByStudentId(yearPart, quarterNum, lessonType, addDate, orderDisClan.getStudentIdTo(), null, 1);
            if (ratePayToList != null && ratePayToList.size() > 0) {
                processRatePays(ratePayList, ratePayToList, yearPart, quarterNum, studentId, orderDisClan.getStudentIdTo(), lessonType, addDate, 3);
            }
        }
    }

    private void processRatePays(List<RatePay> ratePayList, List<RatePay> ratePayToList, Integer yearPart, Integer quarterNum, Long studentId, Long studentIdTo, Integer lessonType, String addDate, Integer type) {
        // 统计不同科目报读总期数
        Map<Long, Integer> subjectTotalNumMap = new HashMap<>();
        for (RatePay ratePay : ratePayList) {
            Long subjectId = ratePay.getSubjectsId();
            int currentNum = ratePay.getNum();
            subjectTotalNumMap.put(subjectId, subjectTotalNumMap.getOrDefault(subjectId, 0) + currentNum);
        }

        // 报读不同科目的数量
        int distinctSubjectCount = subjectTotalNumMap.size();

        // 已保存的校区id
        Set<Long> processedSchoolIds = new HashSet<>();

        for (RatePay ratePay : ratePayList) {
            Long subjectId = ratePay.getSubjectsId();
            Long schoolId = ratePay.getSchoolId();
            // 当前科目报读总期数
            int subjectTotalNum = subjectTotalNumMap.getOrDefault(subjectId, 0);

            if (type == 1) {
                // 当前科目报读期数小于2，不符合同一科目报读多期条件
                if (subjectTotalNum < 2) {
                    continue;
                }
            } else if (type == 2) {
                // 报读不同科目的数量小于2，不符合不同科目同时报读条件
                if (distinctSubjectCount <= 1) {
                    continue;
                }
            }

            // 获取多期缴费率是否有添加过数据
            RateQuantityPay quantityPay = rateQuantityPayMapper.getRateQuantityPayByStudentId(yearPart, quarterNum, studentId, lessonType, addDate, subjectId);

            if (quantityPay == null) {
                quantityPay = new RateQuantityPay();
                BeanUtils.copyProperties(ratePay, quantityPay);
                quantityPay.setNum(1);
                if (processedSchoolIds.contains(schoolId)) {
                    quantityPay.setSchoolNum(0); // 同一个校区只算一次
                } else {
                    quantityPay.setSchoolNum(1);
                    processedSchoolIds.add(schoolId);
                }
                rateQuantityPayMapper.insert(quantityPay);
            }

            if (type == 3) {
                for (RatePay ratePayTo : ratePayToList) {
                    RateQuantityPayOrder payOrder = rateQuantityPayOrderMapper.getRateQuantityPayOrderByPayId(quantityPay.getId(), ratePayTo.getOrderId());
                    if (payOrder == null) {
                        payOrder = new RateQuantityPayOrder();
                        payOrder.setRateQuantityPayId(quantityPay.getId());
                        // 亲属的订单id
                        payOrder.setOrderId(ratePayTo.getOrderId());
                        rateQuantityPayOrderMapper.insert(payOrder);
                    }
                }
            } else {
                RateQuantityPayOrder payOrder = rateQuantityPayOrderMapper.getRateQuantityPayOrderByPayId(quantityPay.getId(), ratePay.getOrderId());
                if (payOrder == null) {
                    payOrder = new RateQuantityPayOrder();
                    payOrder.setRateQuantityPayId(quantityPay.getId());
                    payOrder.setOrderId(ratePay.getOrderId());
                    rateQuantityPayOrderMapper.insert(payOrder);
                }
            }
        }
    }


}
